package com.strongbj.iot.devices.dam.request.handle.dam;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.dam.common.AbstractTaskDelayedRunnable;
import com.strongbj.iot.devices.dam.common.DAMManager;
import com.strongbj.iot.devices.dam.common.ITaskManager;
import com.strongbj.iot.devices.dam.common.NetMapping;
import com.strongbj.iot.devices.dam.message.DAMMessageFactory;
import com.strongbj.iot.devices.dam.message.MQMessageOfDAM;
import com.strongbj.iot.devices.dam.request.entity.DestServerEntity;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

/**
 * 设置目标服务器
 * @author yuzhantao
 *
 */
public class SetDestServerParamesHandle implements IMessageHandle<MQMessageOfDAM, Object> {
	private static Logger logger = LogManager.getLogger(SetDestServerParamesHandle.class.getName());
	private static final String ACTION_CODE="setDestServerParames";	// 事件处理编码
	private final DAMMessageFactory damMessageFactory = new DAMMessageFactory();  // DAM消息工厂
	
	@Override
	public boolean isHandle(MQMessageOfDAM t) {
		if(t.getActioncode().equals(ACTION_CODE)) {
			return true;
		}else {
			return false;
		}
	}

	/**
	 * 将设置网络参数的信息发送到硬件
	 */
	@Override
	public Object handle(ChannelHandlerContext ctx, MQMessageOfDAM t) {
		final DestServerEntity ds = ((JSONObject) t.getAwsPostdata()).toJavaObject(DestServerEntity.class);
		Channel channel = NetMapping.getInstance().getChannel(ds.getRackConverCode());
		ITaskManager taskManager = DAMManager.getTaskManager(ds.getRackConverCode());
		taskManager.addSendTask(new AbstractTaskDelayedRunnable() {
			@Override
			protected void taskRun() {
				sendDatasToDAM(channel,t,ds);
			}
			
		});
		return null;
	}
	
	private void sendDatasToDAM(Channel channel,MQMessageOfDAM t,DestServerEntity ds) {
		if(channel!=null && channel.isActive()) {
			final byte[] datas = DestServerEntity2Bytes(t.getTimestamp(),ds); // 将网络参数对象转为byte数组，用于发送到dam硬件
			ByteBuf bs  = Unpooled.copiedBuffer(datas);
			ChannelFuture cf = channel.writeAndFlush(bs); 
			// TODO 添加监听,查看发送情况DEBUG
			cf.addListener(new ChannelFutureListener() {

				@Override
				public void operationComplete(ChannelFuture future) throws Exception {
					if(future.isSuccess()) {
						logger.info("WEB下发设置目标服务器命令成功 编号:{} 下发命令={}  ", ds.getRackConverCode(), ByteUtil.byteArrToHexString(datas,true));
					}else {
						logger.error("WEB下发设置目标服务器命令失败 编号:{} 下发命令={}  ", ds.getRackConverCode(),ByteUtil.byteArrToHexString(datas,true));
					}
				}
				
			});
		}else {
			logger.error("{} 主机没有找到指定channel",ds.getRackConverCode());
		}
	}

	/**
	 * 网络参数对象转byte数组
	 * @param np
	 * @return
	 */
	private byte[] DestServerEntity2Bytes(long time,DestServerEntity ds) {
		// 创建
		byte[] serverDatas = new byte[6];
		// TODO 没有设置前4byte协议值
		// 将ip赋值到4byte数组中
		this.setIpToBytes(ds.getDestIp(),serverDatas,0);
		// 将端口写入到8-9字节
		ByteUtil.shortToByteArr(ds.getDestPort(), serverDatas, 4, 0);
		
		// 创建设置目标服务器的指令
		byte[] datas = damMessageFactory.createDAMMessage(
				ByteUtil.longToBytes(time),
				ds.getRackConverCode(), // 设备编号
				(byte)0,		// 设备类型，默认填0
				(byte)0, 		// 版本号，默认填0
				(byte)0x12, 	// 设置目标服务器命令
				serverDatas		// 目标服务器参数数据
			);  // 通过dam消息工厂获取指令
		return datas;
	}
	
	/**
	 * 设置指定*.*.*.*格式的数据转为4byte数组
	 * @param srcString		源数据
	 * @param destBytes		目标数组
	 * @param destOffset	赋值的目标数组偏移量
	 */
	private void setIpToBytes(String srcString,byte[] destBytes,int destOffset) {
		String[] strIps = srcString.split("[.]");
		for(int i=0;i<strIps.length;i++) {
			destBytes[i+destOffset]=Integer.valueOf(strIps[i], 10).byteValue();
		}
	}
}